package com.derbysoft.synxisadapter.dswitch3.translator;

import com.derbysoft.dswitch.dto.hotel.avail.HotelAvailCriteriaDTO;
import com.derbysoft.dswitch.dto.hotel.avail.RoomStayCandidateDTO;
import com.derbysoft.dswitch.dto.hotel.common.StayDateRangeDTO;
import com.derbysoft.dswitch.remote.hotel.dto.HotelAvailRequest;
import com.derbysoft.synxisadapter.commons.dto.synxis.*;
import com.derbysoft.synxisadapter.commons.model.Hotel;
import com.derbysoft.synxisadapter.commons.utils.Constant;
import com.derbysoft.synxisadapter.dswitch2.translator.Translator;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * User: jason
 * Date: 2012-11-21
 */
@Component("ds3AvailRQTranslator")
public class HotelAvailRQTranslator extends AbstractTranslator implements Translator<HotelAvailRequest, OTAHotelAvailRQ, Void> {

    @Override
    public OTAHotelAvailRQ translate(HotelAvailRequest request, Void aVoid) {
        OTAHotelAvailRQ otaHotelAvailRQ = new OTAHotelAvailRQ();
        otaHotelAvailRQ.setPrimaryLangID(Constant.PRIMARY_LANG_ID);
        otaHotelAvailRQ.setPOS(translatePOS(request.getHeader().getSource()));
        otaHotelAvailRQ.setAvailRequestSegments(translateAvailRequestSegments(request));
        return otaHotelAvailRQ;
    }

    private ArrayOfAvailRequestSegment translateAvailRequestSegments(HotelAvailRequest request) {
        ArrayOfAvailRequestSegment arrayOfAvailRequestSegment = createArrayOfAvailRequestSegment();
        arrayOfAvailRequestSegment.getAvailRequestSegment().add(translateAvailRequestSegment(request));
        return arrayOfAvailRequestSegment;
    }

    private AvailRequestSegment translateAvailRequestSegment(HotelAvailRequest request) {
        AvailRequestSegment availRequestSegment = createAvailRequestSegment();
        availRequestSegment.setStayDateRange(translateStayDateRange(request.getHotelAvailRQ().getAvailCriteria().getStayDateRange()));
        availRequestSegment.setRoomStayCandidates(translateRoomStayCandidates(request.getHotelAvailRQ().getAvailCriteria()));
        availRequestSegment.setHotelSearchCriteria(translateHotelSearchCriteria(request.getHotelAvailRQ().getAvailCriteria().getHotelCodesList()));
        return availRequestSegment;
    }

    private ArrayOfRoomStayCandidate translateRoomStayCandidates(HotelAvailCriteriaDTO availCriteria) {
        ArrayOfRoomStayCandidate arrayOfRoomStayCandidate = createArrayOfRoomStayCandidate();
        arrayOfRoomStayCandidate.getRoomStayCandidate().add(translateRoomStayCandidate(availCriteria.getRoomStayCandidate()));
        return arrayOfRoomStayCandidate;
    }

    private RoomStayCandidate translateRoomStayCandidate(RoomStayCandidateDTO roomStayCandidateDTO) {
        RoomStayCandidate roomStayCandidate = createRoomStayCandidate();
        roomStayCandidate.setQuantity(1);
        ArrayOfGuestCount arrayOfGuestCount = createArrayOfGuestCount();
        GuestCount adultCount = createGuestCount();
        adultCount.setAgeQualifyingCode(10);
        adultCount.setCount(roomStayCandidateDTO.getAdultCount());
        arrayOfGuestCount.getGuestCount().add(adultCount);
        if (roomStayCandidateDTO.getChildCount() > 0) {
            GuestCount childCount = createGuestCount();
            childCount.setCount(roomStayCandidateDTO.getChildCount());
            childCount.setAgeQualifyingCode(8);
            arrayOfGuestCount.getGuestCount().add(childCount);
        }
        roomStayCandidate.setGuestCounts(arrayOfGuestCount);
        return roomStayCandidate;
    }

    private StayDateRangeType translateStayDateRange(StayDateRangeDTO stayDateRange) {
        StayDateRangeType stayDateRangeType = createStayDateRangeType();
        stayDateRangeType.setStart(stayDateRange.getCheckin());
        stayDateRangeType.setEnd(stayDateRange.getCheckout());
        return stayDateRangeType;
    }

    private ArrayOfHotelSearchCriterion translateHotelSearchCriteria(List<String> hotels) {
        ArrayOfHotelSearchCriterion arrayOfHotelSearchCriterion = createArrayOfHotelSearchCriterion();
        for (String hotelCode : hotels) {
            arrayOfHotelSearchCriterion.getCriterion().add(translateCriterion(loadHotel(hotelCode)));
        }
        return arrayOfHotelSearchCriterion;
    }

    private HotelSearchCriterion translateCriterion(Hotel hotel) {
        HotelSearchCriterion criterion = createHotelSearchCriterion();
        HotelReferenceGroup hotelReferenceGroup = createHotelReferenceGroup();
        hotelReferenceGroup.setHotelCode(hotel.getId());
        criterion.setHotelRef(hotelReferenceGroup);
        return criterion;
    }
}
